﻿using SqlPerfomance.V2.DAL;
using SqlPerfomance.V2.DomainModel.Enums;
using SqlPerfomance.V2.DomainModel.Models;
using SqlPerfomance.V2.DomainModel.NodeTree.Interfaces;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SqlPerfomance.V2.WpfClient
{
	/// <summary>
	/// Interaction logic for StartWindow.xaml
	/// </summary>
	public partial class StartWindow : Window
	{
		public StartWindow()
		{
			InitializeComponent();
		}

		private void btn_alTree_Click(object sender, RoutedEventArgs e)
		{
			AdjancyList al = new AdjancyList(GetCheckedCOnnectionString());
			al.Visibility = System.Windows.Visibility.Visible;
		}

		private void btn_mpTree_Click(object sender, RoutedEventArgs e)
		{
            MaterializedPath mp = new MaterializedPath(GetCheckedCOnnectionString());
			mp.Visibility = System.Windows.Visibility.Visible;
		}

		private void btn_nsTree_Click(object sender, RoutedEventArgs e)
		{
            NestedSet ns = new NestedSet(GetCheckedCOnnectionString());
			ns.Visibility = System.Windows.Visibility.Visible;
		}

        private void btn_generate_trees_Click(object sender, RoutedEventArgs e)
        {
            int nodesCnt = 0;
            int nestingLevel = 0;
            if(!int.TryParse(txt_nodes_cnt.Text, out nodesCnt) || !int.TryParse(txt_nesting_level.Text, out nestingLevel))
            {
                MessageBox.Show("incorrect data!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if(nodesCnt <=0 || nestingLevel <= 0)
            {
                MessageBox.Show("incorrect data!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            lbl_state.Content = "generating of trees...";
            SetButtonsEnabled(false);
            GenerateTrees(nodesCnt, nestingLevel, GetCheckedCOnnectionString());
            SetButtonsEnabled(true);
            lbl_state.Content = "the trees was generated successfully!";
        }

        private void btn_run_tests_Click(object sender, RoutedEventArgs e)
        {
            RunTests runTests = new RunTests();
            runTests.Visibility = System.Windows.Visibility.Visible;
        }

        private void SetButtonsEnabled(bool enabled)
        {
            btn_alTree.IsEnabled = btn_mpTree.IsEnabled = btn_nsTree.IsEnabled = btn_run_tests.IsEnabled = enabled;
        }

        private void GenerateTrees(int nodesCount, int nestingLevel, ConnectionStrings connectionString)
        {
            var commonTreeRepository = new CommonTreeRepository();
            var commonTree = commonTreeRepository.CreateCommonTree(nodesCount, nestingLevel);

            Task[] tasks = new Task[3];

            tasks[0] = Task.Factory.StartNew(() =>
            {
                var mpRepo = new MaterializedPathTreeRepository();
                mpRepo.ClearTable(connectionString, AppSettingsHelper.MpTableName);
                var mpTree = mpRepo.CreateTree((INode<CommonTreeNode>)commonTree);
                mpRepo.SaveRange(mpTree.Nodes, connectionString);
            });

            tasks[1] = Task.Factory.StartNew(() =>
            {
                var alRepo = new AdjancyListTreeRepository();
                alRepo.ClearTable(connectionString, AppSettingsHelper.AlTableName);
                var alTree = alRepo.CreateTree((INode<CommonTreeNode>)commonTree);
                alRepo.SaveRange(alTree.Nodes, connectionString);
            });

            tasks[2] = Task.Factory.StartNew(() =>
            {
                var nsRepo = new NestedSetTreeRepository();
                nsRepo.ClearTable(connectionString, AppSettingsHelper.NsTableName);
                var nsTree = nsRepo.CreateTree((INode<CommonTreeNode>)commonTree);
                nsRepo.SaveRange(nsTree.Nodes, connectionString);

            });

            Task.WaitAll(tasks);
        }

        private ConnectionStrings GetCheckedCOnnectionString()
        {
            return radio_sqlServer.IsChecked.HasValue && radio_sqlServer.IsChecked.Value ? ConnectionStrings.SqlServerConnectionString 
                : ConnectionStrings.MySqlConnectionString;
        }
	}
}
